import { ElMessage } from 'element-plus';
import dayjs from 'dayjs';
import service from './request.js';

// 日志级别
const LOG_LEVELS = {
  DEBUG: 'debug',
  INFO: 'info',
  WARN: 'warn',
  ERROR: 'error',
  FATAL: 'fatal'
};

// 当前日志级别
let currentLogLevel = LOG_LEVELS.DEBUG;

// 日志存储
let logs = [];
const MAX_LOGS = 1000;

// 是否启用控制台输出
let consoleEnabled = true;

// 是否启用本地存储
let localStorageEnabled = true;
const STORAGE_KEY = 'frontend_logs';

// 是否启用日志上传
let uploadEnabled = false;
let uploadUrl = '';
let uploadInterval = 60000; // 默认60秒上传一次
let lastUploadTime = 0;

class Logger {
  constructor(moduleName = 'app') {
    this.moduleName = moduleName;
    
    // 初始化时从本地存储加载日志配置
    this.loadConfig();
  }

  // 设置日志级别
  setLogLevel(level) {
    if (LOG_LEVELS[level.toUpperCase()]) {
      currentLogLevel = level.toLowerCase();
      this.saveConfig();
      this.info(`日志级别已设置为: ${currentLogLevel}`);
    }
  }

  // 启用/禁用控制台输出
  setConsoleEnabled(enabled) {
    consoleEnabled = enabled;
    this.saveConfig();
  }

  // 启用/禁用本地存储
  setLocalStorageEnabled(enabled) {
    localStorageEnabled = enabled;
    this.saveConfig();
    if (!enabled) {
      try {
        localStorage.removeItem(STORAGE_KEY);
      } catch (e) {
        // 忽略存储错误
      }
    }
  }

  // 配置日志上传
  configureUpload(url, interval = 60000) {
    uploadEnabled = !!url;
    uploadUrl = url;
    uploadInterval = interval;
    this.saveConfig();
    
    if (uploadEnabled) {
      this.startUploadInterval();
    }
  }

  // 开始定期上传日志
  startUploadInterval() {
    if (this.uploadTimer) {
      clearInterval(this.uploadTimer);
    }
    
    this.uploadTimer = setInterval(() => {
      this.uploadLogs();
    }, uploadInterval);
  }

  // 上传日志到服务器
  async uploadLogs() {
    if (!uploadEnabled || !uploadUrl || logs.length === 0) {
      return;
    }

    const now = Date.now();
    // 避免过于频繁地上传
    if (now - lastUploadTime < uploadInterval / 2) {
      return;
    }

    try {
      const logsToUpload = [...logs];
      lastUploadTime = now;
      
      await service.post(uploadUrl, {
        logs: logsToUpload,
        timestamp: now,
        environment: process.env.NODE_ENV || 'development'
      });
      
      // 上传成功后清空已上传的日志
      logs = logs.filter(log => !logsToUpload.includes(log));
      
    } catch (error) {
      this.error('上传日志失败:', {
        error: error.message,
        stack: error.stack
      });
      // 不上传失败时不影响应用运行
    }
  }

  // 保存配置到本地存储
  saveConfig() {
    try {
      localStorage.setItem('logger_config', JSON.stringify({
        logLevel: currentLogLevel,
        consoleEnabled,
        localStorageEnabled,
        uploadEnabled,
        uploadUrl,
        uploadInterval
      }));
    } catch (e) {
      // 忽略存储错误
    }
  }

  // 从本地存储加载配置
  loadConfig() {
    try {
      const config = JSON.parse(localStorage.getItem('logger_config'));
      if (config) {
        currentLogLevel = config.logLevel || LOG_LEVELS.DEBUG;
        consoleEnabled = config.consoleEnabled !== false;
        localStorageEnabled = config.localStorageEnabled !== false;
        uploadEnabled = config.uploadEnabled || false;
        uploadUrl = config.uploadUrl || '';
        uploadInterval = config.uploadInterval || 60000;
      }
    } catch (e) {
      // 忽略加载错误，使用默认配置
    }
  }

  // 检查日志级别是否应该被记录
  shouldLog(level) {
    const levels = [LOG_LEVELS.DEBUG, LOG_LEVELS.INFO, LOG_LEVELS.WARN, LOG_LEVELS.ERROR, LOG_LEVELS.FATAL];
    return levels.indexOf(level.toLowerCase()) >= levels.indexOf(currentLogLevel);
  }

  // 创建日志条目
  createLogEntry(level, message, data = null) {
    const logEntry = {
      id: Date.now() + Math.random().toString(36).substr(2, 9),
      timestamp: dayjs().format('YYYY-MM-DD HH:mm:ss.SSS'),
      module: this.moduleName,
      level: level.toUpperCase(),
      message,
      data: data && typeof data === 'object' ? { ...data } : data,
      userAgent: navigator.userAgent,
      screen: `${window.screen.width}x${window.screen.height}`,
      url: window.location.href,
      userId: localStorage.getItem('userId') || 'anonymous'
    };

    // 限制日志数量
    if (logs.length >= MAX_LOGS) {
      logs.shift();
    }
    logs.push(logEntry);

    // 保存到本地存储
    if (localStorageEnabled) {
      try {
        const logsToStore = logs.slice(-200); // 只保存最近200条日志
        localStorage.setItem(STORAGE_KEY, JSON.stringify(logsToStore));
      } catch (e) {
        // 忽略存储错误
      }
    }

    return logEntry;
  }

  // 输出到控制台
  logToConsole(logEntry) {
    if (!consoleEnabled) return;

    const { level, module, message, data, timestamp } = logEntry;
    const logMessage = `[${timestamp}] [${level}] [${module}] ${message}`;

    switch (level) {
      case 'DEBUG':
        console.debug(logMessage, data || '');
        break;
      case 'INFO':
        console.info(logMessage, data || '');
        break;
      case 'WARN':
        console.warn(logMessage, data || '');
        break;
      case 'ERROR':
      case 'FATAL':
        console.error(logMessage, data || '');
        break;
    }
  }

  // 调试日志
  debug(message, data = null) {
    if (this.shouldLog(LOG_LEVELS.DEBUG)) {
      const logEntry = this.createLogEntry(LOG_LEVELS.DEBUG, message, data);
      this.logToConsole(logEntry);
    }
    return this;
  }

  // 信息日志
  info(message, data = null) {
    if (this.shouldLog(LOG_LEVELS.INFO)) {
      const logEntry = this.createLogEntry(LOG_LEVELS.INFO, message, data);
      this.logToConsole(logEntry);
    }
    return this;
  }

  // 警告日志
  warn(message, data = null) {
    if (this.shouldLog(LOG_LEVELS.WARN)) {
      const logEntry = this.createLogEntry(LOG_LEVELS.WARN, message, data);
      this.logToConsole(logEntry);
    }
    return this;
  }

  // 错误日志
  error(message, data = null, showNotification = false) {
    if (this.shouldLog(LOG_LEVELS.ERROR)) {
      const logEntry = this.createLogEntry(LOG_LEVELS.ERROR, message, data);
      this.logToConsole(logEntry);
      
      // 可选地显示错误通知
      if (showNotification) {
        ElMessage.error({
          message: message,
          duration: 5000,
          showClose: true
        });
      }
    }
    return this;
  }

  // 致命错误日志
  fatal(message, data = null, showNotification = true) {
    const logEntry = this.createLogEntry(LOG_LEVELS.FATAL, message, data);
    this.logToConsole(logEntry);
    
    // 默认显示致命错误通知
    if (showNotification) {
      ElMessage.error({
        message: message,
        duration: 10000,
        showClose: true
      });
    }
    
    // 尝试立即上传致命错误日志
    if (uploadEnabled) {
      this.uploadLogs();
    }
    
    return this;
  }

  // 记录业务操作日志
  logBusiness(operation, userId, details) {
    this.info(`业务操作: [操作=${operation}, 用户=${userId}] ${details}`, {
      operationType: 'business',
      operation,
      userId
    });
    return this;
  }

  // 记录系统事件日志
  logSystemEvent(event, details) {
    this.info(`系统事件: [事件=${event}] ${details}`, {
      operationType: 'system',
      event
    });
    return this;
  }

  // 记录安全事件日志
  logSecurityEvent(event, username, details) {
    this.info(`安全事件: [事件=${event}, 用户=${username}] ${details}`, {
      operationType: 'security',
      event,
      username
    });
    return this;
  }

  // 记录性能日志
  logPerformance(operation, startTime, endTime) {
    const duration = endTime - startTime;
    this.info(`性能监控: [操作=${operation}] 耗时=${duration}ms`, {
      operationType: 'performance',
      operation,
      duration,
      startTime,
      endTime
    });
    if (duration > 1000) { // 超过1秒的操作记录警告
      this.warn(`性能警告: [操作=${operation}] 耗时过长: ${duration}ms`, {
        operationType: 'performance_warning',
        operation,
        duration
      });
    }
    return this;
  }

  // 敏感信息掩码处理
  maskSensitiveInfo(info) {
    if (!info || typeof info !== 'string') {
      return info;
    }
    // 简单的密码掩码处理
    if (info.includes('password') || info.includes('token')) {
      return info.replace(/(password|token)\s*[:=]\s*"[^"]*"/gi, '$1: ***');
    }
    return info;
  }

  // 格式化异常信息
  formatException(e) {
    if (!e) {
      return '无异常信息';
    }
    let message = '';
    if (e instanceof Error) {
      message = `${e.name}: ${e.message}`;
      if (e.stack) {
        const stackLines = e.stack.split('\n');
        message += '\n' + stackLines.slice(0, 6).join('\n');
        if (stackLines.length > 6) {
          message += `\n... ${stackLines.length - 6} more lines`;
        }
      }
    } else {
      message = JSON.stringify(e);
    }
    return message;
  }

  // 参数校验并记录日志
  validateParams(...params) {
    const allValid = params.every(param => param !== null && param !== undefined);
    if (!allValid) {
      this.warn('参数校验失败: 存在空参数');
    }
    return allValid;
  }

  // 记录API请求
  apiRequest(url, method, params = null, data = null) {
    if (this.shouldLog(LOG_LEVELS.DEBUG)) {
      const maskedParams = params ? this.maskSensitiveInfo(JSON.stringify(params)) : null;
      const maskedData = data ? this.maskSensitiveInfo(JSON.stringify(data)) : null;
      
      this.info(`API请求: ${method.toUpperCase()} ${url}`, {
        method,
        params: maskedParams ? JSON.parse(maskedParams) : null,
        data: maskedData ? JSON.parse(maskedData) : null
      });
    }
    return this;
  }

  // 记录API响应
  apiResponse(url, method, status, responseData = null) {
    if (status >= 200 && status < 300) {
      this.info(`API响应: ${status} ${method.toUpperCase()} ${url}`, responseData);
    } else {
      this.error(`API响应错误: ${status} ${method.toUpperCase()} ${url}`, responseData);
    }
    return this;
  }

  // 获取所有日志
  getAllLogs() {
    return [...logs];
  }

  // 清空所有日志
  clearLogs() {
    logs = [];
    try {
      localStorage.removeItem(STORAGE_KEY);
    } catch (e) {
      // 忽略存储错误
    }
    this.info('日志已清空');
    return this;
  }

  // 导出日志
  exportLogs() {
    const blob = new Blob([JSON.stringify(logs, null, 2)], { type: 'application/json' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `frontend_logs_${dayjs().format('YYYYMMDD_HHmmss')}.json`;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
    this.info('日志已导出');
  }
}

// 创建全局日志实例
const globalLogger = new Logger();

// 为常见模块创建日志实例
const moduleLoggers = {
  app: new Logger('app'),
  api: new Logger('api'),
  auth: new Logger('auth'),
  router: new Logger('router'),
  store: new Logger('store'),
  component: new Logger('component')
};

// 创建新的模块日志实例
function createLogger(moduleName) {
  return new Logger(moduleName);
}

export default {
  // 全局日志方法
  debug: globalLogger.debug.bind(globalLogger),
  info: globalLogger.info.bind(globalLogger),
  warn: globalLogger.warn.bind(globalLogger),
  error: globalLogger.error.bind(globalLogger),
  fatal: globalLogger.fatal.bind(globalLogger),
  apiRequest: globalLogger.apiRequest.bind(globalLogger),
  apiResponse: globalLogger.apiResponse.bind(globalLogger),
  logBusiness: globalLogger.logBusiness.bind(globalLogger),
  logSystemEvent: globalLogger.logSystemEvent.bind(globalLogger),
  logSecurityEvent: globalLogger.logSecurityEvent.bind(globalLogger),
  logPerformance: globalLogger.logPerformance.bind(globalLogger),
  
  // 工具方法
  maskSensitiveInfo: globalLogger.maskSensitiveInfo.bind(globalLogger),
  formatException: globalLogger.formatException.bind(globalLogger),
  validateParams: globalLogger.validateParams.bind(globalLogger),
  
  // 模块日志
  modules: moduleLoggers,
  createLogger,
  
  // 配置方法
  setLogLevel: globalLogger.setLogLevel.bind(globalLogger),
  setConsoleEnabled: globalLogger.setConsoleEnabled.bind(globalLogger),
  setLocalStorageEnabled: globalLogger.setLocalStorageEnabled.bind(globalLogger),
  configureUpload: globalLogger.configureUpload.bind(globalLogger),
  
  // 日志管理方法
  getAllLogs: globalLogger.getAllLogs.bind(globalLogger),
  clearLogs: globalLogger.clearLogs.bind(globalLogger),
  exportLogs: globalLogger.exportLogs.bind(globalLogger),
  
  // 日志级别常量
  LEVELS: LOG_LEVELS
};